package com.sakura.system.service.impl.xyimpl;

//import com.xiaoxu.cinema.pojo.Record;
//import com.xiaoxu.cinema.mapper.CardMapper;
//import com.xiaoxu.cinema.pojo.Card;
//import com.xiaoxu.cinema.service.CardService;
//import com.xiaoxu.cinema.service.RecordService;
import com.sakura.system.dao.xydao.CardMapper;
import com.sakura.system.entity.xy.Card;
import com.sakura.system.entity.xy.Record;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;

@Service
public class CardServiceImpl implements CardService {
    @Resource
    CardMapper cardMapper;
    @Resource
    RecordService recordService;
    /**
     * 根据会员ID获取卡片数据
     *
     * @param memberId 会员的唯一标识符
     * @return 返回一个卡片数据列表，这些卡片属于指定的会员
     */
    @Override
    public List<Card> getCardData(String memberId) {
        // 通过会员ID查询卡片数据
        return cardMapper.selectCardByMemberId(memberId);
    }

    /**
     * 根据卡牌ID获取卡牌数据。
     *
     * @param cardId 卡牌的唯一标识符。
     * @return 返回与指定ID匹配的卡牌对象。如果找不到，则返回null。
     */
    @Override
    public Card getCardDataById(String cardId) {
        // 通过ID查询卡牌信息
        return cardMapper.selectCardById(cardId);
    }



    /**
     * 注册卡片到系统中。
     *
     * @param memberId 会员ID，用于关联卡片和会员。
     * 该方法会为会员生成一张新卡，初始化卡的余额、积分、损失为0，并将卡与会员绑定。
     * 新卡的ID使用UUID生成，并去除其中的连字符。
     */
    @Override
    public void registerCard(String memberId) {
        // 使用UUID生成卡ID，并移除连字符
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");

        // 创建新卡对象并设置基本信息
        Card card = new Card();
        card.setcardId(uuid);
        card.setBalance(0);
        card.setIntegral(0);
        card.setLose(0);
        card.setmemberId(memberId);

        // 将新卡插入数据库
        cardMapper.insertCard(card);
    }


    /**
     * 根据卡牌ID删除卡牌信息。
     *
     * @param cardId 卡牌的唯一标识符，用于指定要删除的卡牌。
     * @return 无返回值。
     */
    @Override
    public void deleteCardById(String cardId) {
        // 通过卡牌ID调用卡牌映射器删除对应的卡牌记录
        cardMapper.deleteCardById(cardId);
    }

    /**
     * 重新发行卡片。
     * 首先通过卡号获取卡片信息，然后删除与该卡相关的所有记录，接着删除卡片本身，
     * 之后为该卡片生成一个新的UUID作为卡号，并将卡片状态重置为未丢失，
     * 最后将更新后的卡片信息插入数据库，并返回新的卡号。
     *
     * @param cardId 原始卡片的ID。
     * @return 新生成的卡片ID。
     */
    @Override
    public String reissueCard(String cardId) {
        Card card = this.getCardDataById(cardId);
        // 删除与该卡相关的所有记录，以解决外键依赖问题
        //由于在记录表中有外键依赖，所以必须先删除
        recordService.deleteRecordByCardId(cardId);
        deleteCardById(cardId);
        // 生成新的UUID并设置为卡号，同时重置卡片状态
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        card.setcardId(uuid);
        card.setLose(0);
        // 插入更新后的卡片信息到数据库
        cardMapper.insertCard(card);
        return uuid;
    }


    /**
     * 处理卡片丢失的情况。
     * 对于指定的卡片，将其丢失状态更新为1，即标记为丢失。
     *
     * @param cardId 需要标记为丢失的卡片的ID。
     */
    @Override
    public void loseCard(String cardId) {
        Card card = new Card(); // 创建一个新的卡片对象
        card.setcardId(cardId); // 设置卡片ID
        card.setLose(1); // 设置卡片的丢失状态为1
        cardMapper.updateCardById(card); // 根据ID更新卡片信息
    }


    /**
     * 取消指定卡牌的方法。
     * 该方法通过卡牌ID来找到对应的卡牌，将卡牌的状态设置为失效，并更新到数据库中。
     *
     * @param cardId 卡牌的唯一标识符，用于找到需要取消的卡牌。
     * @return 无返回值。
     */
    @Override
    public void cancelCard(String cardId) {
        Card card = new Card(); // 创建一个新的卡牌对象
        card.setcardId(cardId); // 设置卡牌ID
        card.setLose(0); // 将卡牌的失效状态设置为0，表示失效
        cardMapper.updateCardById(card); // 根据ID更新卡牌信息到数据库
    }

    /**
     * 为指定卡号的卡进行充值。
     * @param cardId 卡的唯一标识符。
     * @param value 充值的金额。
     */
    @Override
    public void rechargeCard(String cardId, int value) {
        // 根据卡号获取卡片信息
        Card card = this.getCardDataById(cardId);
        // 对卡片余额进行增加
        card.setBalance(card.getBalance()+value);

        // 创建消费记录，此处为充值操作，故消费类型设为0
        Record record = new Record();
        record.setcardId(cardId);
        record.setspendType(0);
        record.setValue(value);

        // 更新卡片信息到数据库
        cardMapper.updateCardById(card);
        // 插入消费记录到数据库
        recordService.insertRecord(record);
    }


    /**
     * 消费卡内余额，同时更新卡片信息和生成消费记录。
     *
     * @param cardId 卡的ID，用于标识进行消费的卡片。
     * @param price 消费的金额，单位为货币单位。
     * @param integral 消费获得的积分。
     * 该方法首先根据卡ID获取卡片信息，然后更新卡片的余额和积分，
     * 并生成两条消费记录，一条表示货币消费，一条表示积分获得，
     * 最后更新卡片信息到数据库，并插入两条消费记录。
     */
    @Override
    public void consumeCard(String cardId, int price, int integral) {
        Card card = this.getCardDataById(cardId);
        // 更新卡片余额和积分
        card.setBalance(card.getBalance()-price);
        card.setIntegral(card.getIntegral()+integral);

        // 创建消费记录
        Record record1 = new Record();
        record1.setcardId(cardId);
        record1.setspendType(0); // 0代表货币消费
        record1.setValue(price*-1); // 负值表示消费
        Record record2 = new Record();
        record2.setcardId(cardId);
        record2.setspendType(1); // 1代表积分获得
        record2.setValue(integral); // 积分获得的值为正值
        // 更新数据库中的卡片信息
        cardMapper.updateCardById(card);
        // 插入消费记录到数据库
        recordService.insertRecord(record1);
        recordService.insertRecord(record2);
    }


    /**
     * 会员积分兑换功能实现。
     * 通过会员ID查询其所有卡号及对应积分，然后根据消耗的积分情况进行积分扣除并生成消费记录。
     *
     * @param memberId 会员ID，用于查询会员的卡号及积分。
     * @param consumeIntegral 消费的积分数量。
     */
    @Override
    public void exchangeIntegral(String memberId, int consumeIntegral) {
        // 查询会员所有的卡以及对应的积分
        List<Card> cards = cardMapper.selectCardByMemberId(memberId);
        for (Card card:
             cards) {
            // 判断如果当前卡的积分小于等于要消耗的积分，则将此卡积分扣完并生成消费记录
            if(card.getIntegral()<=consumeIntegral){
                consumeIntegral-=card.getIntegral();
                // 创建消费记录对象
                Record record2 = new Record();
                record2.setcardId(card.getcardId());
                record2.setspendType(1); // 消费类型设置为1，代表积分消耗
                record2.setValue(card.getIntegral()*-1); // 记录消耗的积分数值，为负数
                card.setIntegral(0); // 将卡中积分设置为0
                cardMapper.updateCardById(card); // 更新卡中积分信息
                recordService.insertRecord(record2); // 插入消费记录
            }else{
                // 当前卡积分大于消耗的积分，仅消耗所需积分并生成消费记录
                Record record = new Record();
                record.setcardId(card.getcardId());
                record.setspendType(1); // 消费类型设置为1，代表积分消耗
                record.setValue(consumeIntegral*-1); // 记录消耗的积分数值，为负数
                card.setIntegral(card.getIntegral()-consumeIntegral); // 更新卡中剩余积分
                cardMapper.updateCardById(card); // 更新卡中积分信息
                recordService.insertRecord(record); // 插入消费记录
                break; // 找到一张满足消耗的卡后即可结束循环
            }
        }
    }


    /**
     * 获取卡片数量
     *
     * 本方法不需要参数，通过调用cardMapper的selectCardCount方法，查询数据库中卡片的总数，并将该总数作为Long类型返回。
     *
     * @return Long 表示卡片的总数
     */
    @Override
    public Long getCardNum() {
        return cardMapper.selectCardCount(); // 查询并返回卡片总数
    }

    /**
     * 根据模糊查询条件获取会员卡ID列表。
     *
     * @param memberId 会员ID，用于查询与该会员相关的卡信息。
     * @param cardId 卡ID的部分字符串，用于进行模糊查询。
     * @return 返回一个字符串列表，包含匹配查询条件的卡ID。
     */
    @Override
    public List<String> getCardIdByFuzzyQuery(String memberId, String cardId) {
        // 调用cardMapper的selectCardIdByFuzzyQuery方法，传入memberId和cardId进行模糊查询，返回匹配的卡ID列表
        List<String> cardList = cardMapper.selectCardIdByFuzzyQuery(memberId, cardId);
        return cardList;
    }

    /**
     * 根据卡号获取卡片信息。
     *
     * @param cardId 卡片的唯一标识符。
     * @return 返回对应卡号的卡片对象，如果找不到则返回null。
     */
    @Override
    public Card getCardByCardId(String cardId) {
        // 通过卡号查询卡片信息
        return cardMapper.selectCardById(cardId);
    }


}
